package v1

import (
	"bufio"
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"gin-demo/pkg/setting"
	"gin-demo/pkg/util"
	"github.com/gin-gonic/gin"
	"io"
	"net/http"
	"strings"
)

// 对接 deepseek 的api
var (
	msgFlag3 string // 不知道这个干啥的
)

// 初始化
func init() {
	flag.StringVar(&msgFlag3, "msg3", "", "文本消息")
}

/**
介绍：
role  	   含义
system     表示可以设置机器人的人设
assistant  表示机器人回复内容
user	   表示用户提问问题
*/

type ChatCompletionsRequest struct {
	Model    string     `json:"model"`
	Stream   bool       `json:"stream"`
	Messages []*Message `json:"messages"`
}

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

type ChatCompletionResponse struct {
	ID      string `json:"id"`
	Object  string `json:"object"`
	Created int64  `json:"created"`
	Model   string `json:"model"`
	Choices []struct {
		Delta struct {
			Content string `json:"content"`
		} `json:"delta"`
		Index int `json:"index"`
	} `json:"choices"`
}

// 请求
// 参数介绍具体查看文档：https://api-docs.deepseek.com/zh-cn/

// DeepSeekStreamRequest deeepseek 用stream的方式返回
func DeepSeekStreamRequest(c *gin.Context) {
	message := c.Query("message") // 是个json
	// systemContent := c.DefaultQuery("system_content", "")

	returnObj := util.NewResponseSuccess()

	msgInput := &MessageInput{}

	errInput := json.Unmarshal([]byte(message), msgInput)
	if errInput != nil {
		returnObj.Code = 422
		returnObj.Msg = "请求参数发生了错误"
		util.ResponseSuccess(c, returnObj)
		return
	}
	if msgInput.Message == "" {
		returnObj.Code = 422
		returnObj.Msg = "message参数不能为空"
		util.ResponseSuccess(c, returnObj)
		return
	}

	// 创建请求体
	reqBody := ChatCompletionsRequest{
		Model:  "deepseek-chat", // 替换为实际的模型名称
		Stream: true,
		Messages: []*Message{
			{
				Role:    "system",
				Content: msgInput.SystemContent,
			},
			{
				Role:    "user",
				Content: msgInput.Message,
			},
		},
	}

	reqJson, _ := json.Marshal(reqBody)
	fmt.Println("发起请求，req=" + string(reqJson))

	// 将请求体转换为 JSON
	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		fmt.Println("JSON 编码错误:", err)
		return
	}

	// 创建 HTTP 请求
	req, err := http.NewRequest("POST", setting.DeepSeekConf.END_POINT, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Println("创建请求失败:", err)
		return
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+setting.DeepSeekConf.API_KEY)
	req.Header.Set("Accept", "text/event-stream") // 要求服务器返回 SSE 格式

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("请求失败:", err)
		return
	}
	defer resp.Body.Close()

	// 检查响应状态码

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		fmt.Printf("请求失败，状态码: %d, 响应: %s\n", resp.StatusCode, string(body))
		return
	}

	//fmt.Printf("请求成功，状态码: %d, 响应: %s\n", resp.StatusCode, string(body))

	// 处理 SSE 流式响应
	reader := bufio.NewReader(resp.Body)
	for {
		line, err := reader.ReadBytes('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			fmt.Println("读取流式响应失败:", err)
			return
		}

		// 检查是否是 SSE 数据行
		if bytes.HasPrefix(line, []byte("data: ")) {
			// 提取 JSON 数据
			jsonData := line[6:] // 去掉 "data: " 前缀
			//fmt.Println(string(line))
			//if string(jsonData) == "[DONE]" {
			if strings.Contains(strings.ToLower(string(jsonData)), "done") {
				fmt.Println("message: finish mark")
				c.SSEvent("message", "{\"delta\":{\"content\":\"finish\"},\"index\":0}")
				break
			}
			var response ChatCompletionResponse
			if err := json.Unmarshal(jsonData, &response); err != nil {
				fmt.Println("解析 JSON 失败:", err)
				continue
			}

			// 输出流式响应的内容
			for _, choice := range response.Choices {
				jsonData2, err := json.Marshal(choice)
				if err != nil {
					fmt.Println("Error marshalling to JSON:", err)
					return
				}
				fmt.Printf("data: %s\n\n", string(jsonData2)) // 以 SSE 格式输出
				c.SSEvent("message", choice)                  // c.SSEvent 这个是gin框架封装的方法
			}
			//go handleSseMessage(c, response)
		}
	}
}

func handleSseMessage(c *gin.Context, response ChatCompletionResponse) {
	// 输出流式响应的内容
	for _, choice := range response.Choices {
		jsonData2, err := json.Marshal(choice)
		if err != nil {
			fmt.Println("Error marshalling to JSON:", err)
			return
		}
		fmt.Printf("data---: %s\n\n", string(jsonData2)) // 以 SSE 格式输出
		//c.SSEvent("message", choice)                  // c.SSEvent 这个是gin框架封装的方法
		go handleSend(c, choice)
	}
}

func handleSend(c *gin.Context, choice any) {
	c.SSEvent("message", choice) // c.SSEvent 这个是gin框架封装的方法
}
